package com.crpc.factory;

import cn.hutool.core.util.ObjectUtil;
import com.crpc.config.CrpcProperties;
import com.crpc.config.RegisterProperties;
import com.crpc.core.CrpcBootStrap;
import com.crpc.core.ReferenceConfig;
import com.crpc.core.compress.CompressorFactory;
import com.crpc.core.compress.CompressorWrapper;
import com.crpc.core.config.Configuration;
import com.crpc.core.discovery.RegistryConfig;
import com.crpc.core.serialize.SerializerFactory;
import com.crpc.core.serialize.SerializerWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
public class ProxyFactory {
    private static final Map<Class<?>, Object> CACHE_PROXY = new ConcurrentHashMap<>();
    @Autowired
    CrpcProperties crpcProperties;
    @Autowired
    RegisterProperties registerProperties;

    public <T> T gerProxy(Class<T> clazz) {
        if (ObjectUtil.isNotNull(CACHE_PROXY.get(clazz))) {
            return (T) CACHE_PROXY.get(clazz);
        }
        ReferenceConfig<T> reference = new ReferenceConfig<>();
        reference.setInterfaceProvider(clazz);
        Configuration configuration = CrpcBootStrap.getInstance().getConfiguration();
        configuration.setApplicationName(crpcProperties.getCrpcName());
        configuration.setRegistryConfig(new RegistryConfig(registerProperties.getRegistryType().getType() + "://" + registerProperties.getHost() + ":" + registerProperties.getPort()));
        SerializerWrapper serializerWrapper = SerializerFactory.getSerializer(crpcProperties.getSerializerType().getCode());
        configuration.setSerializer(serializerWrapper.getSerializer());
        CompressorWrapper compressorWrapper = CompressorFactory.getCompressor(crpcProperties.getCompressorType().getCode());
        configuration.setCompressor(compressorWrapper.getCompressor());
        CrpcBootStrap.getInstance().reference(reference);
        CACHE_PROXY.put(clazz, reference.get());
        return reference.get();
    }
}
